package sweepmine;

import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.Random;

public class SweepMine extends JFrame implements ActionListener, MouseListener {
    ImageIcon bg;
    Image temp;
    JLabel background;
    // 主面板
    JPanel jp1 = new JPanel();
    // 初级扫雷面板
    JPanel jp2;
    // 中级扫雷面板
    JPanel jp3;
    // 高级扫雷面板
    JPanel jp4;
    // 自定义数据面板
    JPanel jp5 = new JPanel();
    // 自定义扫雷面板
    JPanel jp6;
    // 联机扫雷组队面板
    JPanel jp7 = new JPanel();
    // 重载面板
    JPanel panel1 = new JPanel();
    JTextField te1 = new JTextField(50);
    JTextField te2 = new JTextField(50);
    JTextField te3 = new JTextField(50);
    JTextField te4 = new JTextField(50);
    JTextField te5 = new JTextField(50);
    ImageIcon[] icon, iconChange;
    int[][] save, isMine, isEnable, rightClick, right;
    JButton[][] block;
    int[] count1, count2;
    boolean tt, flag, firstTry;
    boolean cooperate;
    boolean move;
    boolean moveFromOther;
    boolean matching;
    int level, row, column, mine, num, bonEnd, mineEnd;
    int num1, num2;
    Random ron;
    int flagCount, time;
    int side;
    Timer timer;
    Record record = new Record();
    JButton[] bon;
    Client client;
    String sendMsg, recMsg;
    Font fon1 = new Font("黑体", 1, 80);
    Font fon2 = new Font("黑体", 1, 15);
    Font fon3 = new Font("黑体", 1, 24);
    JButton bt1 = new JButton("初级扫雷");
    JButton bt2 = new JButton("中级扫雷");
    JButton bt3 = new JButton("高级扫雷");
    JButton bt4 = new JButton("自定义扫雷");
    JButton eraseb = new JButton("清除存档");
    JButton loadb = new JButton("加载存档");
    JButton bt5 = new JButton("联机扫雷");
    JButton bt6 = new JButton("统计信息");
    JButton bt7 = new JButton("关于");
    JButton bt8 = new JButton("返回主界面");// 初级扫雷面板
    JButton bt9 = new JButton("返回主界面");// 自定义数据面板
    JButton bt10 = new JButton("确认");
    JButton bt11 = new JButton("返回主界面");// 中级扫雷面板
    JButton bt12 = new JButton("返回主界面");// 高级扫雷面板
    JButton bt13 = new JButton("返回主界面");// 自定义扫雷面板
    JButton bt14 = new JButton("返回主界面");
    JButton bt15 = new JButton("返回主界面");// 联机组队面板
    JButton bt16 = new JButton("进入房间");
    JLabel la1 = new JLabel("鸭兵扫雷");
    JLabel la2 = new JLabel("输入自定义行数（9-20）：");
    JLabel la3 = new JLabel("输入自定义列数（9-40）：");
    JLabel la4 = new JLabel("输入自定义雷数（1-400）：");
    JLabel la5 = new JLabel("输入房间号（10-90）：");
    JLabel la6 = new JLabel("房间双人成行，如被阻塞请耐心等待...");

    // 居中显示
    public void showOnCenter() {
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension frameSize = getSize();
        if (frameSize.height > screenSize.height)
            frameSize.height = screenSize.height;
        if (frameSize.width > screenSize.width)
            frameSize.width = screenSize.width;
        setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
    }

    // 改变图片大小
    public void changeIcon(int width, int height) {
        ImageIcon icon11;
        for (int i = 0; i < 14; i++) {
            Image temp = icon[i].getImage().getScaledInstance(width, height,
                    icon[i].getImage().SCALE_DEFAULT);
            icon11 = new ImageIcon(temp);
            iconChange[i] = icon11;
        }
    }

    // 扫雷面板初始化
    public void Initiation(JPanel jp, int row, int column, int mine) {
        save = new int[row][column];
        isMine = new int[row][column];
        isEnable = new int[row][column];
        rightClick = new int[row][column];
        right = new int[row][column];
        mineEnd = 0;
        bonEnd = 0;
        flagCount = mine;
        time = 0;
        firstTry = true;
        cooperate = false;
        move = true;
        moveFromOther = false;
        block = new JButton[row][column];
        recMsg = "";
        setTitle("扫雷");
        changeIcon(32, 32);

        // 计时及雷数显示区初始化
        bon = new JButton[4];
        for (int i = 0; i < 4; i++) {
            bon[i] = new JButton("");
            bon[i].setMargin(new Insets(0, 0, 0, 0));
        }
        bon[0].setBounds(-55 + column * 16, 20, 40, 40);
        bon[0].setIcon(icon[14]);
        bon[0].setBorder(new BevelBorder(BevelBorder.RAISED));
        bon[1].setBounds(-15 + column * 16, 20, 50, 40);
        bon[1].setBackground(Color.CYAN);
        bon[1].setFont(fon3);
        bon[1].setText(String.valueOf(time));
        bon[1].setBorder(new BevelBorder(BevelBorder.LOWERED));
        bon[2].setBounds(45 + column * 16, 20, 40, 40);
        bon[2].setIcon(icon[15]);
        bon[2].setBorder(new BevelBorder(BevelBorder.RAISED));
        bon[3].setBounds(85 + column * 16, 20, 50, 40);
        bon[3].setBackground(Color.CYAN);
        bon[3].setFont(fon3);
        bon[3].setText(mine + "");
        bon[3].setBorder(new BevelBorder(BevelBorder.LOWERED));
        jp.add(bon[0]);
        jp.add(bon[1]);
        jp.add(bon[2]);
        jp.add(bon[3]);

        // 雷区方格初始化
        for (int i = 1; i < row - 1; i++) {
            for (int j = 1; j < column - 1; j++) {
                block[i][j] = new JButton();
                block[i][j].setBounds(40 + 32 * j, 45 + 32 * i, 32, 32);
                block[i][j].setMargin(new Insets(0, 0, 0, 0));
                block[i][j].setBorder(BorderFactory.createLineBorder(
                        Color.black, 1));
                block[i][j].setIcon(iconChange[10]);
                save[i][j] = 10;
                block[i][j].addActionListener(this);
                block[i][j].addMouseListener(this);
                jp.add(block[i][j]);
            }
        }
        jp.revalidate();

        // 退出事件
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                if (!bon[1].getText().equalsIgnoreCase("0")) {
                    int a = JOptionPane.showConfirmDialog(null, "确认退出游戏？",
                            "确认退出", JOptionPane.YES_NO_OPTION);
                    if (a == JOptionPane.YES_OPTION) {
                        System.exit(0);
                    }
                } else
                    System.exit(0);
            }
        });
    }

    // 计时
    public void countTime() {
        timer = new Timer(1000, this);
    }

    public SweepMine(String s) {
        setTitle(s);
        setSize(1000, 600);
        setResizable(false);
        setLayout(null);

        // 初始化图片
        icon = new ImageIcon[16];
        iconChange = new ImageIcon[16];
        for (int i = 0; i < 16; i++)
            icon[i] = new ImageIcon("icon/" + i + ".jpg");

        // 设置按钮，标签位置与样式
        bt1.setBounds(800, 40, 100, 50);
        bt2.setBounds(800, 100, 100, 50);
        bt3.setBounds(800, 160, 100, 50);
        bt4.setBounds(800, 220, 100, 50);
        eraseb.setBounds(200, 460, 100, 50);
        loadb.setBounds(800, 280, 100, 50);
        bt5.setBounds(800, 340, 100, 50);
        bt6.setBounds(800, 400, 100, 50);
        bt7.setBounds(800, 460, 100, 50);
        bt9.setBounds(200, 200, 100, 50);
        bt10.setBounds(75, 200, 100, 50);
        bt15.setBounds(200, 200, 100, 50);
        bt16.setBounds(75, 200, 100, 50);
        la1.setFont(fon1);
        la1.setBounds(100, 100, 400, 200);
        la2.setFont(fon2);
        la2.setBounds(50, 50, 200, 15);
        la3.setFont(fon2);
        la3.setBounds(50, 100, 200, 15);
        la4.setFont(fon2);
        la4.setBounds(50, 150, 200, 15);
        la5.setFont(fon2);
        la5.setBounds(50, 50, 200, 15);
        la6.setFont(fon2);
        la6.setBounds(50, 150, 300, 15);
        te1.setBounds(250, 50, 100, 15);
        te2.setBounds(250, 100, 100, 15);
        te3.setBounds(250, 150, 100, 15);
        te4.setBounds(250, 150, 100, 15);
        te5.setBounds(50, 75, 100, 50);

        // 主界面背景设置
        bg = new ImageIcon("icon/114514.png");
        background = new JLabel();
        Dimension frameSize = getSize();
        temp = bg.getImage().getScaledInstance(frameSize.width, frameSize.height, bg.getImage().SCALE_DEFAULT);
        bg = new ImageIcon(temp);
        background.setIcon(bg);
        background.setBounds(0, 0, frameSize.width, frameSize.height);

        // 主界面面板设置
        jp1.add(bt1);
        jp1.add(bt2);
        jp1.add(bt3);
        jp1.add(bt4);
        jp1.add(eraseb);
        jp1.add(loadb);
        jp1.add(bt5);
        jp1.add(bt6);
        jp1.add(bt7);
        jp1.add(la1);
        jp1.setLayout(null);
        jp1.add(background);

        // 自定义数据面板设置
        jp5.setBackground(Color.WHITE);
        jp5.add(la2);
        jp5.add(la3);
        jp5.add(la4);
        jp5.add(te1);
        jp5.add(te2);
        jp5.add(te3);
        jp5.add(bt9);
        jp5.add(bt10);
        jp5.setLayout(null);

        // 联机组队面板设置
        jp7.setBackground(Color.WHITE);
        jp7.add(la5);
        jp7.add(la6);
        jp7.add(te5);
        jp7.add(bt15);
        jp7.add(bt16);
        jp7.setLayout(null);

        // 主界面初始化
        setContentPane(jp1);
        showOnCenter();
        setVisible(true);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        // 按钮事件监听设置
        bt1.addActionListener(this);
        bt2.addActionListener(this);
        bt3.addActionListener(this);
        bt4.addActionListener(this);
        bt5.addActionListener(this);
        eraseb.addActionListener(this);
        loadb.addActionListener(this);
        bt6.addActionListener(this);
        bt7.addActionListener(this);
        bt8.addActionListener(this);
        bt9.addActionListener(this);
        bt10.addActionListener(this);
        bt11.addActionListener(this);
        bt12.addActionListener(this);
        bt13.addActionListener(this);
        bt14.addActionListener(this);
        bt15.addActionListener(this);
        bt16.addActionListener(this);
    }

    public void actionPerformed(ActionEvent e) {
        // 统计信息查看
        if (e.getSource() == bt6) {
            new Thread(new Message("统计信息")).start();
        }

        // 作者
        if (e.getSource() == bt7) {
            JOptionPane.showMessageDialog(this, "作者:忠诚的鸭兵", "关于", JOptionPane.INFORMATION_MESSAGE);
        }

        // 初级扫雷
        if (e.getSource() == bt1) {
            row = 11;
            column = 11;
            mine = 10;
            jp2 = new JPanel();
            jp2.setBackground(Color.WHITE);
            bt8.setBounds(column * 32 - 25, row * 32 + 30, 100, 30);
            jp2.add(bt8);
            jp2.setLayout(null);
            Initiation(jp2, row, column, mine);
            setContentPane(jp2);
            setSize(column * 32 + 100, row * 32 + 100);
            showOnCenter();
            arrangeMine();
            countTime();
            level = 0;
        }

        // 中级扫雷
        if (e.getSource() == bt2) {
            row = 18;
            column = 18;
            mine = 40;
            jp3 = new JPanel();
            jp3.setBackground(Color.WHITE);
            bt11.setBounds(column * 32 - 25, row * 32 + 30, 100, 30);
            jp3.add(bt11);
            jp3.setLayout(null);
            Initiation(jp3, row, column, mine);
            setContentPane(jp3);
            setSize(column * 32 + 100, row * 32 + 100);
            showOnCenter();
            arrangeMine();
            countTime();
            level = 1;
        }

        // 高级扫雷
        if (e.getSource() == bt3) {
            row = 18;
            column = 32;
            mine = 99;
            jp4 = new JPanel();
            jp4.setBackground(Color.WHITE);
            bt12.setBounds(column * 32 - 25, row * 32 + 30, 100, 30);
            jp4.add(bt12);
            jp4.setLayout(null);
            Initiation(jp4, row, column, mine);
            setContentPane(jp4);
            setSize(column * 32 + 100, row * 32 + 100);
            showOnCenter();
            arrangeMine();
            countTime();
            level = 2;
        }

        // 自定义扫雷数据设置
        if (e.getSource() == bt4) {
            setContentPane(jp5);
            setSize(400, 400);
            showOnCenter();
        }

        // 联机扫雷组队
        if (e.getSource() == bt5) {
            setContentPane(jp7);
            setSize(400, 400);
            showOnCenter();
        }

        // 联机扫雷
        if (e.getSource() == bt16) {
            String room = te5.getText();
            try {
                // 房间号临界判断（数值越界）
                if (Integer.parseInt(room) < 10 || Integer.parseInt(room) > 90) {
                    JOptionPane.showMessageDialog(this, "房间号超出范围！", "Error", JOptionPane.INFORMATION_MESSAGE);
                } else {
                    // 发送房间申请
                    String ini = room + "99999";
                    String address = "172.20.10.3"; // 需手动修改
                    int port = 6868;
                    try {
                        row = 11;
                        column = 11;
                        mine = 10;
                        client = new Client(this, ini, address, port, row, column);
                        client.start();
                        matching = true;
                        new Thread(() -> {
                            do {
                                System.out.println("waiting");
                            } while (client.getWaiting() && matching);
                            if (!client.getWaiting()) {
                                // 获取行动方信息
                                side = Integer.parseInt(client.getServerReply()) % 10;
                                System.out.println("side=" + side);

                                // 初始化棋盘
                                jp2 = new JPanel();
                                jp2.setBackground(Color.WHITE);
                                bt8.setBounds(column * 32 - 25, row * 32 + 30, 100, 30);
                                jp2.add(bt8);
                                jp2.setLayout(null);
                                Initiation(jp2, row, column, mine);
                                setContentPane(jp2);
                                setSize(column * 32 + 100, row * 32 + 100);
                                showOnCenter();
                                arrangeMine();
                                countTime();
                                level = 0;

                                // 判断先后手
                                cooperate = true;
                                if (side == 1) {
                                    move = true;
                                    setTitle("扫雷");
                                } else {
                                    move = false;
                                    setTitle("扫雷（非我方行动回合）");
                                    client.recArray();
                                    do {
                                        System.out.println("waiting for array");
                                    } while (client.isWaitingArray());
                                    isMine = client.getMine();
                                }

                                // 开始接收对局信息
                                client.startRec();
                                new Thread(() -> {
                                    while (true) {
                                        synchronized (recMsg) {
                                            if (!(recMsg.equals(client.getRecMsg()))) {
                                                recMsg = client.getRecMsg();
                                                int recMsgInt = Integer.parseInt(recMsg);
                                                if (recMsgInt == 6666666) { // 对方胜利信号处理
                                                    client.sendMessage("9999999");
                                                    win();
                                                    break;
                                                } else if (recMsgInt == 8888888) { // 对方失败信号处理
                                                    client.sendMessage("9999999");
                                                    interrupt();
                                                    break;
                                                } else if (recMsgInt == 7777777) { // 对方中途退出信号处理
                                                    client.sendMessage("9999999");
                                                    break;
                                                } else {
                                                    // 我方在接收对方信息后模拟对方上一步行动
                                                    if (recMsgInt % 10 == side) {
                                                        System.out.println(recMsgInt / 1000);
                                                        System.out.println((recMsgInt / 10) % 100);
                                                        int tranRow = recMsgInt / 1000;
                                                        int tranCol = (recMsgInt / 10) % 100;
                                                        move = true;
                                                        setTitle("扫雷");
                                                        moveFromOther = true;
                                                        MouseEvent event = new MouseEvent(block[tranRow][tranCol],
                                                                MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(),
                                                                InputEvent.BUTTON1_DOWN_MASK, 0, 0, 1, false);
                                                        block[tranRow][tranCol].dispatchEvent(event);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }).start();
                            }
                        }).start();
                    } catch (IOException ex) {
                        ex.getStackTrace();
                    }
                }
            } catch (NumberFormatException ne) { // 房间号不为数字时提示
                JOptionPane.showMessageDialog(this, "非法输入！", "Error", JOptionPane.INFORMATION_MESSAGE);
            }
        }

        // 清除存档
        if (e.getSource() == eraseb) {
            int a = JOptionPane.showConfirmDialog(this, "是否清除存档", "确认清除", JOptionPane.YES_NO_OPTION);
            if (a == JOptionPane.YES_OPTION) {
                record.clearsave();
                // System.out.println("清除成功！");
            }
        }

        // 加载页面
        if (e.getSource() == loadb) {
            int a = JOptionPane.showConfirmDialog(this, "是否加载上一局游戏", "确认加载", JOptionPane.YES_NO_OPTION);
            if (a == JOptionPane.YES_OPTION) {
                load();
                // System.out.println("加载成功！");
            }
        }

        // 返回主界面
        if (e.getSource() == bt8 || e.getSource() == bt11
                || e.getSource() == bt12 || e.getSource() == bt13
                || e.getSource() == bt14) {
            if (cooperate) {
                int a = JOptionPane.showConfirmDialog(this, "游戏正在进行，确认退出游戏？(提示：联机模式退出后需要重新组队)",
                        "确认退出", JOptionPane.YES_NO_OPTION);
                if (a == JOptionPane.YES_OPTION) {
                    client.sendMessage("8888888");
                    cooperate = false;
                    setTitle("扫雷");
                    setContentPane(jp1);
                    setSize(1000, 600);
                    showOnCenter();
                }
            } else {
                if (!bon[1].getText().equalsIgnoreCase("0")) {
                    int a = JOptionPane.showConfirmDialog(this, "游戏正在进行，确认退出游戏？", "确认退出", JOptionPane.YES_NO_OPTION);
                    if (a == JOptionPane.YES_OPTION) {
                        int b = JOptionPane.showConfirmDialog(this, "是否保存游戏，以便您下次游玩？", "确认保存",
                                JOptionPane.YES_NO_OPTION);
                        if (b == JOptionPane.YES_OPTION) {
                            saveDate();
                            JOptionPane.showMessageDialog(this, "保存成功！", "保存结果", JOptionPane.INFORMATION_MESSAGE);
                        }
                        setTitle("扫雷");
                        setContentPane(jp1);
                        setSize(1000, 600);
                        showOnCenter();
                    }
                } else {
                    setTitle("扫雷");
                    setContentPane(jp1);
                    setSize(1000, 600);
                    showOnCenter();
                }
            }
        }
        if (e.getSource() == bt9) {
            setContentPane(jp1);
            setSize(1000, 600);
            showOnCenter();
        }
        if (e.getSource() == bt15) {
            try {
                if (client != null) {
                    int a = JOptionPane.showConfirmDialog(this, "当前正在等待队友中，是否确认退出？", "确认退出", JOptionPane.YES_NO_OPTION);
                    if (a == JOptionPane.YES_OPTION) {
                        client.closeSocket();
                        matching = false;
                        setContentPane(jp1);
                        setSize(1000, 600);
                        showOnCenter();
                    }
                } else {
                    setContentPane(jp1);
                    setSize(1000, 600);
                    showOnCenter();
                }
            } catch (IOException ioException) {
                ioException.getStackTrace();
            }
        }

        // 自定义扫雷
        if (e.getSource() == bt10) {
            try {
                if (Integer.parseInt(te1.getText()) < 9 || Integer.parseInt(te1.getText()) > 20
                        || Integer.parseInt(te2.getText()) < 9 || Integer.parseInt(te2.getText()) > 40
                        || Integer.parseInt(te3.getText()) < 1 || Integer.parseInt(te3.getText()) > 400
                        || Integer.parseInt(te3
                                .getText()) > (Integer.parseInt(te1.getText()) * Integer.parseInt(te2.getText()) - 1)) {
                    JOptionPane.showMessageDialog(this, "自定义行数列数或雷数超出范围！", "Error", JOptionPane.INFORMATION_MESSAGE);
                } else {
                    row = Integer.parseInt(te1.getText()) + 2;
                    column = Integer.parseInt(te2.getText()) + 2;
                    mine = Integer.parseInt(te3.getText());
                    jp6 = new JPanel();
                    jp6.setBackground(Color.WHITE);
                    bt13.setBounds(column * 32 - 25, row * 32 + 30, 100, 30);
                    jp6.add(bt13);
                    jp6.setLayout(null);
                    Initiation(jp6, row, column, mine);
                    setContentPane(jp6);
                    setSize(column * 32 + 100, row * 32 + 100);
                    showOnCenter();
                    arrangeMine();
                    countTime();
                    level = 3;
                }
            } catch (NumberFormatException exception) {
                JOptionPane.showMessageDialog(this, "非法输入！", "Error", JOptionPane.INFORMATION_MESSAGE);
            }
        }

        // 计时
        if (e.getSource() == timer) {
            time++;
            bon[1].setText(time + "");
        }

    }

    @Override
    public void mouseClicked(MouseEvent e) {// 单击鼠标时执行的操作

    }

    // 鼠标离开
    @Override
    public void mouseExited(MouseEvent e) {// 鼠标离开组件时执行的操作
        for (int i = 1; i < row - 1; i++) {
            for (int j = 1; j < column - 1; j++) {
                if (isEnable[i][j] != 1 && rightClick[i][j] % 3 == 0) {
                    if (e.getSource() == block[i][j])
                        block[i][j].setIcon(iconChange[10]);
                }
            }
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {// 鼠标在组件上按下时执行的操作
        for (int i = 1; i < row - 1; i++) {
            for (int j = 1; j < column - 1; j++) {
                // 鼠标左右击（联机禁用）
                if (e.getModifiersEx() == (e.BUTTON3_DOWN_MASK + e.BUTTON1_DOWN_MASK)
                        && e.getSource() == block[i][j] && isEnable[i][j] == 1 && !cooperate) {
                    int number3 = countFlag(i, j);
                    if (isMine[i][j] == number3) {
                        openFlag(i, j);
                    } else {
                        openFlagFail(i, j, 1);
                    }
                }

                // 鼠标右击
                if (e.getSource() == block[i][j] && isEnable[i][j] != 1
                        && e.getModifiersEx() == e.BUTTON3_DOWN_MASK) {
                    if (time == 0)
                        timer.start();
                    rightClick[i][j]++;
                    if (rightClick[i][j] % 3 == 1) {
                        block[i][j].setIcon(iconChange[11]);
                        save[i][j] = 11;
                        // System.out.println(i + " " + j + " " + save[i][j] + " ");
                        right[i][j] = 1;
                        flagCount--;
                        bon[3].setText("" + flagCount);
                        if (isMine[i][j] == 10)
                            mineEnd++;
                        if (mineEnd == mine) {
                            win();
                        }
                    }
                    if (rightClick[i][j] % 3 == 2) {
                        block[i][j].setIcon(iconChange[12]);
                        save[i][j] = 12;
                        right[i][j] = 0;
                        flagCount++;
                        bon[3].setText("" + flagCount);
                        if (isMine[i][j] == 10)
                            mineEnd--;
                        if (mineEnd == mine) {
                            win();
                        }
                    }
                    if (rightClick[i][j] % 3 == 0) {
                        block[i][j].setIcon(iconChange[10]);
                        save[i][j] = 10;
                    }
                }
            }
        }

        // 鼠标左击
        if (e.getModifiersEx() == e.BUTTON1_DOWN_MASK) {
            if (!cooperate || move) {
                for (int i = 1; i < row - 1; i++) {
                    for (int j = 1; j < column - 1; j++) {
                        if (e.getSource() == block[i][j]) {
                            if (cooperate) {
                                // 根据点击方块确定信息row(2)+column(2)+side(1)
                                if (i < 10 && j < 10) {
                                    sendMsg = "" + 0 + i + 0 + j + (side + 1) % 2;
                                } else if (i > 10 && j < 10) {
                                    sendMsg = "" + i + 0 + j + (side + 1) % 2;
                                } else if (i < 10 && j > 10) {
                                    sendMsg = "" + 0 + i + j + (side + 1) % 2;
                                } else {
                                    sendMsg = "" + i + j + (side + 1) % 2;
                                }
                            }
                            if (time == 0)
                                timer.start();
                            if (firstTry) {
                                firstClick(i, j);
                                if (cooperate && !moveFromOther && side == 1) {
                                    // 先手方第一次点击后确定盘面并发送至后手方
                                    client.sendA(isMine, row, column);
                                    client.sendMessage(sendMsg);
                                    move = false;
                                    setTitle("扫雷（非我方行动回合）");
                                }
                            } else {
                                if (isEnable[i][j] != 1 && right[i][j] != 1) {
                                    if (cooperate && !moveFromOther) {
                                        client.sendMessage(sendMsg);
                                        move = false;
                                        setTitle("扫雷（非我方行动回合）");
                                    }
                                    if (isMine[i][j] != 10)
                                        open(i, j);
                                    else {
                                        fail();
                                    }
                                    if (bonEnd == ((row - 2) * (column - 2)) - mine)
                                        win();
                                } else if (isEnable[i][j] != 1 && moveFromOther) {
                                    if (isMine[i][j] != 10)
                                        open(i, j);
                                    else {
                                        fail();
                                    }
                                    if (bonEnd == ((row - 2) * (column - 2)) - mine)
                                        win();
                                }
                            }
                        }
                    }
                }
                if (cooperate && moveFromOther) {
                    moveFromOther = false;
                }
            }
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {// 鼠标释放时执行的操作
        for (int i = 1; i < row - 1; i++) {
            for (int j = 1; j < column - 1; j++) {
                // 鼠标左右击
                if (e.getSource() == block[i][j] && isEnable[i][j] == 1
                        && tt == true) {
                    openFlagFail(i, j, 0);
                }
            }
        }
    }

    @Override
    public void mouseEntered(MouseEvent e) {// 鼠标移到时执行的操作
        for (int i = 1; i < row - 1; i++) {
            for (int j = 1; j < column - 1; j++) {
                if (isEnable[i][j] != 1 && rightClick[i][j] % 3 == 0) {
                    if (e.getSource() == block[i][j])
                        block[i][j].setIcon(iconChange[13]);
                }
            }
        }
    }

    // 数周围红旗数
    public int countFlag(int a, int b) {
        int number2 = 0;
        for (int i = a - 1; i < a + 2; i++) {
            for (int j = b - 1; j < b + 2; j++) {
                if (right[i][j] == 1) {
                    number2++;
                }
            }
        }
        return number2;
    }

    // 鼠标左右击
    public void openFlag(int a, int b) {
        int num3 = 0;
        for (int i = a - 1; i < a + 2; i++) {
            for (int j = b - 1; j < b + 2; j++) {
                if (isEnable[i][j] != 1 && i >= 1 && j >= 1 && i < row - 1
                        && j < column - 1) {
                    if (isMine[i][j] != 10 && right[i][j] != 1) {
                        open(i, j);
                    }
                    if (isMine[i][j] == 10 && right[i][j] != 1)
                        num3++;
                    if (bonEnd == ((row - 2) * (column - 2)) - mine) {
                        win();
                        return;
                    }
                }
            }
        }
        if (num3 != 0) {
            fail();
        }
    }

    // 鼠标左右击时旗数和显示数字不同
    public void openFlagFail(int a, int b, int c) {

        for (int i = a - 1; i < a + 2; i++) {
            for (int j = b - 1; j < b + 2; j++) {
                if (c == 1 && isEnable[i][j] != 1 && right[i][j] != 1 && i >= 1
                        && j >= 1 && i < row - 1 && j < column - 1) {
                    block[i][j].setIcon(iconChange[13]);
                    tt = true;
                }
                if (c == 0 && isEnable[i][j] != 1 && right[i][j] != 1 && i >= 1
                        && j >= 1 && i < row - 1 && j < column - 1) {
                    block[i][j].setIcon(iconChange[10]);
                    tt = false;
                }
            }
        }
    }

    // 判断布雷是否重复
    public boolean check(int a, int[] b, int c) {
        for (int i = 0; i <= c; i++) {
            if (a == b[i])
                return true;
        }
        return false;
    }

    // 布雷
    public void arrangeMine() {
        count1 = new int[(row - 2) * (column - 2)];
        count2 = new int[mine];
        num1 = 0;
        num2 = 0;
        ron = new Random();
        for (int i = 0; i < mine; i++) {
            num2 = ron.nextInt((row - 2) * (column - 2));
            count2[i] = num2;
            flag = check(num2, count2, i - 1);
            while (flag) {
                num2 = ron.nextInt((row - 2) * (column - 2));
                count2[i] = num2;
                flag = check(num2, count2, i - 1);
            }
            count1[num2] = 10;
        }
        for (int i = 1; i < row - 1; i++) {
            for (int j = 1; j < column - 1; j++) {
                isMine[i][j] = count1[num1];
                num1++;
            }
        }
    }

    // 第一次点时不遇雷
    public void firstClick(int a, int b) {
        int i;
        do {
            i = countMine(a, b);
            firstTry = false;
            if (i != 0) {
                arrangeMine();
                firstTry = true;
            }
        } while (firstTry);
        open(a, b);
    }

    // 数雷
    public int countMine(int a, int b) {
        int number1 = 0;
        for (int i = a - 1; i < a + 2; i++) {
            for (int j = b - 1; j < b + 2; j++) {
                if (isMine[i][j] == 10) {
                    number1++;
                }
            }
        }
        return number1;
    }

    // 掀开
    public void open(int a, int b) {
        num = 0;
        bonEnd++;
        isEnable[a][b] = 1;
        num = countMine(a, b);
        isMine[a][b] = num;
        block[a][b].setIcon(iconChange[num]);
        save[a][b] = num;
        if (num == 0)
            isNull(a, b);

    }

    // 掀开的按钮周围没有雷
    public void isNull(int a, int b) {
        for (int i = a - 1; i < a + 2; i++) {
            for (int j = b - 1; j < b + 2; j++) {
                if ((i != a || j != b) && i >= 1 && j >= 1 && i < row - 1
                        && j < column - 1) {
                    if (isEnable[i][j] != 1 && isMine[i][j] != 10
                            && right[i][j] != 1) {
                        open(i, j);
                    }
                }
            }
        }
    }

    // 掀开所有的雷
    public void openAllMine() {
        for (int i = 1; i < row - 1; i++) {
            for (int j = 1; j < column - 1; j++) {
                if (isMine[i][j] == 10) {
                    block[i][j].setIcon(iconChange[9]);
                }
            }
        }
    }

    // 胜利
    public void win() {
        if (Integer.parseInt(bon[3].getText()) >= 0) {
            timer.stop();
            System.out.println("win");
            if (!cooperate) {
                record.write(0, level, 1);
                record.write(1, level, Integer.parseInt(bon[1].getText()));
                record.write(2, level, level);
            } else {
                client.sendMessage("6666666");
            }
            new ResultWin("游戏胜利", this);
        }
    }

    // 失败
    public void fail() {
        openAllMine();
        timer.stop();
        System.out.println("lose");
        if (!cooperate) {
            record.write(0, level, 0);
            record.write(2, level, level);
        } else {
            client.sendMessage("7777777");
        }
        new ResultLose("游戏失败", this);
    }

    // 联机被打断
    public void interrupt() {
        timer.stop();
        new Interrupt("队友中途退出", this);
    }

    // 新游戏
    public void newGame() {
        firstTry = true;
        for (int i = 1; i < row - 1; i++) {
            for (int j = 1; j < column - 1; j++) {
                block[i][j].setIcon(iconChange[10]);
                isEnable[i][j] = 0;
                right[i][j] = 0;
                rightClick[i][j] = 0;
                isMine[i][j] = 0;
            }
        }
        arrangeMine();
        mineEnd = 0;
        bonEnd = 0;
        flagCount = mine;
        bon[3].setText("" + mine);
        timer.stop();
        time = 0;
        bon[1].setText("0");
        if (cooperate) {
            if (side == 1) {
                move = true;
                setTitle("扫雷");
            } else {
                move = false;
                setTitle("扫雷（非我方行动回合）");
            }
            recMsg = "";
        }
    }

    // 重新开始
    public void restart() {
        for (int i = 1; i < row - 1; i++) {
            for (int j = 1; j < column - 1; j++) {
                block[i][j].setIcon(iconChange[10]);
                isEnable[i][j] = 0;
                right[i][j] = 0;
                rightClick[i][j] = 0;
            }
        }
        mineEnd = 0;
        bonEnd = 0;
        flagCount = mine;
        bon[3].setText("" + mine);
        timer.stop();
        time = 0;
        bon[1].setText("0");
        if (cooperate) {
            if (side == 1) {
                move = true;
                setTitle("扫雷");
            } else {
                move = false;
                setTitle("扫雷（非我方行动回合）");
            }
            recMsg = "";
        }
    }

    // 返回主界面（弹窗用）
    public void backMain() {
        setContentPane(jp1);
        setSize(1000, 600);
        showOnCenter();
        setTitle("扫雷");
        if (cooperate) {
            cooperate = false;
            client.sendMessage("9999999");
        }
    }

    // 保存数据
    public void saveDate() {
        // 清除原先存档
        record.clearsave();

        int[] mydata = new int[8]; // 用来保存配置参数的临时参数
        mydata[0] = level;
        mydata[1] = row;
        mydata[2] = column;
        mydata[3] = mine;
        mydata[4] = mineEnd;
        mydata[5] = bonEnd;
        mydata[6] = flagCount;
        mydata[7] = time;

        // System.out.println("内部保存函数运行！");

        // 写入保存数据
        record.writeBasicData(mydata);
        record.writeArray(0, save, row, column);
        record.writeArray(1, isMine, row, column);
        record.writeArray(2, isEnable, row, column);
        record.writeArray(3, rightClick, row, column);
        record.writeArray(4, right, row, column);
    }

    // 加载二维数组配置参数
    public void loadArray(String[] s, int[][] d) {
        int num3 = 0;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < column; j++) {
                d[i][j] = Integer.parseInt(s[num3]);
                num3++;
            }
        }
    }

    // 加载存档图像
    public void loadIcon() {
        for (int i = 1; i < row - 1; i++) {
            for (int j = 1; j < column - 1; j++) {
                block[i][j] = new JButton();
                block[i][j].setBounds(40 + 32 * j, 45 + 32 * i, 32, 32);
                block[i][j].setMargin(new Insets(0, 0, 0, 0));
                block[i][j].setBorder(BorderFactory.createLineBorder(Color.black, 1));
                block[i][j].setIcon(iconChange[save[i][j]]);
                block[i][j].addActionListener(this);
                block[i][j].addMouseListener(this);
                panel1.add(block[i][j]);
            }
        }
    }

    // 加载
    public void load() {
        countTime();
        timer.stop();

        String[] Sbd = record.read(3, -1).split("<>");
        String[] Ssave = record.read(4, -1).split("<>");
        String[] SisMine = record.read(5, -1).split("<>");
        String[] SisEnable = record.read(6, -1).split("<>");
        String[] SrightClick = record.read(7, -1).split("<>");
        String[] Sright = record.read(8, -1).split("<>");

        if (Sbd.length == 1) {
            int a = JOptionPane.showConfirmDialog(this, "存档为空，无法加载", "无法加载", JOptionPane.YES_NO_OPTION);
        }
        level = Integer.parseInt(Sbd[0]);
        row = Integer.parseInt(Sbd[1]);
        column = (Integer.parseInt(Sbd[2]));
        mine = (Integer.parseInt(Sbd[3]));
        mineEnd = Integer.parseInt(Sbd[4]);
        bonEnd = Integer.parseInt(Sbd[5]);
        flagCount = Integer.parseInt(Sbd[6]);
        time = Integer.parseInt(Sbd[7]);
        firstTry = false;
        System.out.println(row + " " + column);

        save = new int[row][column];
        isMine = new int[row][column];
        block = new JButton[row][column];
        isEnable = new int[row][column];
        rightClick = new int[row][column];
        right = new int[row][column];
        loadArray(Ssave, save);
        loadArray(SisMine, isMine);
        loadArray(SisEnable, isEnable);
        loadArray(SrightClick, rightClick);
        loadArray(Sright, right);

        panel1 = new JPanel();
        panel1.revalidate();
        panel1.setBackground(Color.WHITE);
        bt14.setBounds(column * 32 - 25, row * 32 + 30, 100, 30);
        panel1.add(bt14);
        panel1.setLayout(null);
        changeIcon(32, 32); // 待调整
        loadIcon();

        bon = new JButton[4];
        for (int i = 0; i < 4; i++) {
            bon[i] = new JButton("");
            bon[i].setMargin(new Insets(0, 0, 0, 0));
        }
        bon[0].setBounds(-45 + column * 16, 20, 40, 40);
        bon[0].setIcon(icon[14]);
        bon[0].setBorder(new BevelBorder(BevelBorder.RAISED));
        bon[1].setBounds(-5 + column * 16, 20, 40, 40);
        bon[1].setBackground(Color.CYAN);
        bon[1].setFont(fon3);
        bon[1].setText("" + time);
        bon[1].setBorder(new BevelBorder(BevelBorder.LOWERED));
        bon[2].setBounds(45 + column * 16, 20, 40, 40);
        bon[2].setIcon(icon[15]);
        bon[2].setBorder(new BevelBorder(BevelBorder.RAISED));
        bon[3].setBounds(85 + column * 16, 20, 50, 40);
        bon[3].setBackground(Color.CYAN);
        bon[3].setFont(fon3);
        bon[3].setText("" + flagCount);
        bon[3].setBorder(new BevelBorder(BevelBorder.LOWERED));
        panel1.add(bon[0]);
        panel1.add(bon[1]);
        panel1.add(bon[2]);
        panel1.add(bon[3]);

        setContentPane(panel1);
        setSize(column * 32 + 100, row * 32 + 100);
        showOnCenter();
        timer.start();
    }
}